#include <iostream>
#include <fstream>
#include <cmath>
#include <sstream>
#include <cstring>
#include <vector>
#include <iomanip>
#include <time.h>
using namespace std;

void usage(){

    cout << "usage: "<< endl;
    cout << "analizer <namefile.nam>" << endl;

}

struct unit_delay{
    double time;
    double delay;
};

struct unit_delay_total_pacotes{
    double delay_medio;
    int total_pacotes;
};



void sleep(unsigned int mseconds)
{
	clock_t goal = mseconds + clock();
	while (goal > clock());
}

unit_delay_total_pacotes Delay_UDP_Packets(string namefile){

    vector<unit_delay>  resultados;
    ifstream file;
    file.open(namefile.c_str());
    char str[2000];
    string mystr;
//header file
    for(int i=0;i<4;i++)
        file.getline(str,2000);
///////////////
    while(!file.eof())
    {
        file.getline(str,2000);
      //  cout <<str<<endl; //out
        double timeStart,timeEnd;
        char * tokens;
        tokens = strtok (str," ");
        if(tokens[0]=='+'){
          //  cout << str<<endl; // out
            tokens = strtok (NULL, " "); // -t
            tokens = strtok (NULL, " "); // <time>
            timeStart = atof(tokens);
            for(int i=0;i<6;i++)
                tokens = strtok (NULL, " ");
            if (strcmp (tokens,"udp") == 0){
                while(!file.eof())
                {
                    file.getline(str,2000);
                    tokens = strtok (str," ");
                    if(tokens[0]=='r')
                    {
                      // cout << str<<endl;
                        tokens = strtok (NULL, " "); // -t
                        tokens = strtok (NULL, " "); // <time>
                        timeEnd = atof(tokens);
                        for(int i=0;i<6;i++)
                            tokens = strtok (NULL, " ");
                        if (strcmp (tokens,"udp") == 0){
                            unit_delay delay;
                            delay.time = timeEnd;
                            delay.delay = timeEnd-timeStart;
                            resultados.push_back(delay);
                       //     cout<< timeEnd-timeStart<<endl;
                        }
                        break;
                    }
                }
            }

        }
    }

    cout <<endl;
	file.close();

	ofstream output;
    output.open("output_matlab.m");

    output <<"global time;global delay;"<<endl;
    output << "time = ["<<endl;

	vector<unit_delay>::iterator itVectorDelay;
	int i = 0;double sumDelay=0,mediaDelay=0;
    for(itVectorDelay = resultados.begin(); itVectorDelay != resultados.end(); itVectorDelay++)
    {
        unit_delay d = *(itVectorDelay);
     //   cout <<"delay"<<"("<<i++<<"):"<<d.time<<";"<< d.delay<<endl;
        sumDelay+=d.delay;
        output << d.time<<" ";
    }
    output <<"];"<<endl;
    output << "delay = ["<<endl;
    for(itVectorDelay = resultados.begin(); itVectorDelay != resultados.end(); itVectorDelay++)
    {
        unit_delay d = *(itVectorDelay);
        output <<d.delay<<" ";
    }
    output <<"];"<<endl;

    output << "delay_medio = "<<sumDelay/resultados.size()<<";"<<endl;

   // cout << "delay_medio = ["<<sumDelay/resultados.size()<<"];"<<endl;

    output.flush();
    output.close();


    unit_delay_total_pacotes result;
    result.delay_medio = sumDelay/resultados.size();
    result.total_pacotes = resultados.size();
    return result;

}


void Delay_Packets_Per_100_Seg(string namefile){

    vector<unit_delay>  resultados;
    ifstream file;
    double time = 100,janela=1,interval=100;
    file.open(namefile.c_str());
    char str[2000];
    string mystr;
//header file
    for(int i=0;i<4;i++)
        file.getline(str,2000);
///////////////
    while(!file.eof())
    {
        file.getline(str,2000);
      //  cout <<str<<endl; //out
        double timeStart,timeEnd;
        char * tokens;
        tokens = strtok (str," ");
        if(tokens[0]=='+'){
          //  cout << str<<endl; // out
            tokens = strtok (NULL, " "); // -t
            tokens = strtok (NULL, " "); // <time>
            timeStart = atof(tokens);
            for(int i=0;i<6;i++)
                tokens = strtok (NULL, " ");
            if (strcmp (tokens,"udp") == 0){
                while(!file.eof())
                {
                    file.getline(str,2000);
                    tokens = strtok (str," ");
                    if(tokens[0]=='r')
                    {
                      // cout << str<<endl;
                        tokens = strtok (NULL, " "); // -t
                        tokens = strtok (NULL, " "); // <time>
                        timeEnd = atof(tokens);
                        for(int i=0;i<6;i++)
                            tokens = strtok (NULL, " ");
                        if (strcmp (tokens,"udp") == 0){
                            unit_delay delay;
                            delay.time = timeEnd;
                            delay.delay = timeEnd-timeStart;
                            bool flag = false;
                            if(ceil(timeStart)>=time-1 && floor(timeStart)>=time+1){
                                 //....delay
                                 flag=true;
                            }

                            if(flag==false){
                                time+=interval;
                            }
                      //      resultados.push_back(delay);
                       //     cout<< timeEnd-timeStart<<endl;
                        }
                        break;
                    }
                }
            }

        }
    }

    cout <<endl;
	file.close();
   // return result;

}


vector<double> Drop_UDP_Packets_Per_100_Seg(string namefile){

    double time = 100;
    vector<double> vector_droped_packets_per_100;
    int total_droped_per_100_seg=0;

    int total_udp=0;
    ifstream file;
    file.open(namefile.c_str());
    char str[2000];
    string mystr;
//header file
    for(int i=0;i<4;i++)
        file.getline(str,2000);
///////////////
    while(!file.eof())
    {
        file.getline(str,2000);
      //  cout <<str<<endl; //out
        double timeStart;
        char * tokens;
        tokens = strtok (str," ");
        if(tokens[0]=='d'){
             tokens = strtok (NULL, " "); // -t
             tokens = strtok (NULL, " "); // <time>
             timeStart = atof(tokens);

             for(int i=0;i<6;i++)
                tokens = strtok (NULL, " ");
            if (strcmp (tokens,"udp") == 0){
                total_droped_per_100_seg++;
             if(timeStart>time){
                 vector_droped_packets_per_100.push_back(total_droped_per_100_seg);
                // cout << total_droped_per_100_seg <<endl;
                 total_droped_per_100_seg = 0;

                 time+=100;
            }
            }
        }
    }
    file.close();
    return vector_droped_packets_per_100;

}


vector<double> Overhead_Packets_Per_100_Seg(string namefile){

    double time = 100;
    vector<double> vector_overhead_packets_per_100;
    int total_aodv_per_100_seg=0;
    ifstream file;
    file.open(namefile.c_str());
    char str[2000];
    string mystr;
//header file
    for(int i=0;i<4;i++)
        file.getline(str,2000);
///////////////
    while(!file.eof())
    {
        file.getline(str,2000);
      //  cout <<str<<endl; //out
        double timeStart,timeEnd;
        char * tokens;
        tokens = strtok (str," ");
        if(tokens[0]=='+'){
          //  cout << str<<endl; // out
            tokens = strtok (NULL, " "); // -t
            tokens = strtok (NULL, " "); // <time>
            timeStart = atof(tokens);
            for(int i=0;i<6;i++)
                tokens = strtok (NULL, " ");
            if (strcmp (tokens,"aodv") == 0){
                total_aodv_per_100_seg++;
                if(timeStart>time){
                   // cout <<timeStart<< endl;
                   //cout << total_aodv_per_100_seg <<endl;
                    vector_overhead_packets_per_100.push_back(total_aodv_per_100_seg);
                    total_aodv_per_100_seg = 0;
                    // cout << total_aodv_per_100_seg <<endl;
                    time+=100;
                }
            }

        }

    }
    file.close();
    return vector_overhead_packets_per_100;

}



int main(int argc, const char *argv[])
{
	string namefile;
	//system ("matlab -nojvm -r f_test(2,3);exit");
	ofstream output;
    output.open("output");

	if(argc==2){
        namefile=argv[1];
        unit_delay_total_pacotes  result;
         vector<double> resultados_overhead;
        vector<double> resultados_droped;
         result = Delay_UDP_Packets(namefile);
        cout <<"Total_Pacotes_UDP_Recebidos = "<<result.total_pacotes<< endl;
        output  <<"Total_Pacotes_UDP_Recebidos = "<<result.total_pacotes<< endl;
       // cout <<"Total Pacotes UDP perdidos: "<< Drop_UDP_Packets(namefile) << endl;
       // output  <<"Total Pacotes UDP perdidos: "<< Drop_UDP_Packets(namefile) << endl;
        cout <<"Total_Atraso_Medio = "<<result.delay_medio<< endl;
        output <<"Total_Atraso_Medio = "<<result.delay_medio<< endl;
        resultados_overhead =  Overhead_Packets_Per_100_Seg(namefile);


        resultados_droped=  Drop_UDP_Packets_Per_100_Seg(namefile);
        vector<double>::iterator iterator_vector;
        double sum_packtes_overhead=0;
        double sum_packtes_droped=0;
        cout << "time=[ ";
        output << "time=[ ";
        for(int i = 0;i<=resultados_overhead.size();i++){
            cout << i*100 << " ";
            output << i*100 << " ";
        }
        cout << "]"<<endl;
        output << "]"<<endl;
        cout << "overhead=[ 0 ";
        output << "overhead=[ 0 ";
        for(iterator_vector = resultados_overhead.begin(); iterator_vector != resultados_overhead.end(); iterator_vector++)
        {
            double packtes = *(iterator_vector);
            sum_packtes_overhead+= packtes;
            cout <<packtes<<" ";
            output << packtes<<" ";
        }

        cout << "]"<< endl;
        output << "]"<< endl;
        cout << "droped=[ 0 ";
        output << "droped=[ 0 ";
        for(iterator_vector = resultados_droped.begin(); iterator_vector != resultados_droped.end(); iterator_vector++)
        {
            double packtes_droped = *(iterator_vector);
            sum_packtes_droped+= packtes_droped;
            cout <<packtes_droped<<" ";
            output << packtes_droped<<" ";
        }

        cout << "]"<< endl;
        output << "]"<< endl;
        cout<<setw (10);
        output <<setw (10);
        cout << "Total_Overhead_Packtes = " << sum_packtes_overhead << endl;
        output << "Total_Overhead_Packtes = " << sum_packtes_overhead << endl;
        output.flush();
        output.close();
        system ("matlab -nojvm -r run('output_matlab');delay_per_100;exit;");

    }else{
        usage();
        return EXIT_SUCCESS;
    }
	return 0;
}
